﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Runtime.Serialization;
using nwrole.toolbox.sync.extensions;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace nwrole.toolbox.sync.contract
{
    [DataContract]
    public class SyncMessageEnvelope
    {
        // public DataTable MessageData = null;

        [DataMember]
        public bool FirstMessage { get; set; }

        [DataMember]
        public bool LastMessage { get; set; }

        [DataMember]
        public int MessageIndex { get; set; }

        [DataMember]
        public int MessageCount { get; set; }

        [DataMember]
        public string ClientCode { get; set; }

        [DataMember]
        public string MessageType { get; set; }

        [DataMember]
        public String Schema { get; set; }

        [DataMember]
        public byte[] Bytes { get; set; }

        [DataMember]
        public SerializationEnum SerializationType { get; set; }

        [DataMember]
        public Guid MsgCorr { get; set; }

        public enum SerializationEnum
        {
            DataTable,
            Reader
        }

        public SyncMessageEnvelope()
        {
        }

        public SyncMessageEnvelope(string type, string clientCode, byte[] bytes, string schema, Guid guid)
        {
            SerializationType = SerializationEnum.Reader;
            ClientCode = clientCode;
            MessageType = type;
            Bytes = bytes;
            Schema = schema;
            MsgCorr = guid;
        }

        public SyncMessageEnvelope(string type, string clientCode, DataTable table, Guid guid)
        {
            SerializationType = SerializationEnum.DataTable;
            ClientCode = clientCode;
            MessageType = type;
            byte[] bytes = null;
            string schema = null;
            table.LightWeightSerialize(out bytes, out schema);
            Bytes = bytes;
            Schema = schema;
            MsgCorr = guid;
        }

        public DataTable AsDataTable()
        {

            if (SerializationType == SerializationEnum.DataTable)
            {
                return Bytes.LightWeightDeserialize(Schema);
            }
            if (SerializationType == SerializationEnum.Reader)
            {

                DataTable table = new DataTable("OBJEKTSBUNDET");
                // table2.ExtendedProperties.Add("BaseTable.0", "OBJEKTSBUNDET");
                // table2.ExtendedProperties.Add("BaseSchema", "WF");

                object[] row  = null;
                string[] cols = Schema.Split('\t');
                BinaryFormatter serializationFormatter = new BinaryFormatter();
                MemoryStream buffer = new MemoryStream(Bytes);

                // table.MinimumCapacity = itemArrayForRows.Length;
                table.BeginLoadData();
                while (buffer.Position < buffer.Length)
                {

                    row  = (object[])serializationFormatter.Deserialize(buffer);
                    if (table.Columns.Count == 0)
                    {
                        for (int t = 0; t < row.Length; t++)
                        {
                            string[] parts = cols[t].Split(';');
                            string name = parts[0];
                            Type myType = Type.GetType(parts[1]);
                            DataColumn dc = new DataColumn();
                            dc.AllowDBNull = true;
                            dc.ColumnName = name;
                            dc.DataType = myType;
                            table.Columns.Add(dc);
                        }
                    }

                    table.Rows.Add(row);
                }
                table.EndLoadData();

                return table;
            }

            throw new Exception("SerializationType error, can not create datatable"); 
        }


    }
}

/*
{IND_INDEXTALID}
    base {System.ComponentModel.MarshalByValueComponent}: {IND_INDEXTALID}
    AllowDBNull: true
    AutoIncrement: false
    AutoIncrementSeed: 0
    AutoIncrementStep: 1
    Caption: "IND_INDEXTALID"
    ColumnMapping: Element
    ColumnName: "IND_INDEXTALID"
    DataType: {Name = "Decimal" FullName = "System.Decimal"}
    DateTimeMode: UnspecifiedLocal
    DefaultValue: {}
    Expression: ""
    ExtendedProperties: Count = 2
    MaxLength: -1
    Namespace: ""
    Ordinal: 4
    Prefix: ""
    ReadOnly: false
    Table: {OBJEKTSBUNDET}
    Unique: false
*/


